//
//  QRCodeViewController.swift
//  swift_demo_weibo
//
//  Created by 杨兵 on 15/5/15.
//  Copyright (c) 2015年 bing. All rights reserved.
//

import UIKit
import AVFoundation

class QRCodeViewController: UIViewController, UITabBarDelegate {


    @IBOutlet weak var tabberitem: UITabBar!
    
    @IBOutlet weak var animView: UIImageView!
    // 冲击波顶部约束
    @IBOutlet weak var toplayout: NSLayoutConstraint!
    // 获取容器约束
    @IBOutlet weak var heightConstraint: NSLayoutConstraint!
    
    @IBOutlet weak var widthConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        tabberitem.selectedItem = tabberitem.items![0] as? UITabBarItem
        setupAnimation(tabberitem.selectedItem)
        
        // 开始扫描
        scan()
    }

    
    // MARK: - UITabBarDelegate
    // 判断选中的item
    func tabBar(tabBar: UITabBar, didSelectItem item: UITabBarItem!) {
        self.heightConstraint.constant = self.widthConstraint.constant * (item.tag > 0 ? 0.8 : 1)
        setupAnimation(item)
    }
    
    
    /**
        设置扫描动画
    */
    func setupAnimation(item: UITabBarItem!) {
        // 清空视图上的所有动画
        animView.layer.removeAllAnimations()
        // 设置初始约束高度
        toplayout.constant = -heightConstraint.constant
        
        self.view.layer.layoutIfNeeded()
        
        UIView.animateWithDuration(2.0, animations: { () -> Void in
            self.toplayout.constant = self.heightConstraint.constant
            // 设置约束,改变扫描框的高度,条形码框的高度0.8倍
            UIView.setAnimationRepeatCount(MAXFLOAT)
            self.view.layer.layoutIfNeeded()
        })
        
    }
    
    
    
    
    // MARK: - 硬件实现
    // 拍摄会话
    lazy var session: AVCaptureSession = {
        return AVCaptureSession()
        }()
    
    // 摄像头输入设备
    lazy var videoInput: AVCaptureDeviceInput? = {
        // 获取摄像头设备
        if let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) {
            return AVCaptureDeviceInput(device: device, error: nil)
        }
        return nil
        }()
    
    // 数据输出
    lazy var dataoutput: AVCaptureMetadataOutput = {
        return AVCaptureMetadataOutput()
        }()
    
    
    // 预览图
    lazy var previewLayer: AVCaptureVideoPreviewLayer = {
            let layer = AVCaptureVideoPreviewLayer(session: self.session)
            layer.frame = self.view.bounds
            return layer
        }()
    
    
    
    // MARK: - 绘制边线
    // bounds
    // corners
    lazy var drawlayer: CALayer = {
        let layer = CALayer()
        layer.frame = self.view.frame
        return layer
    }()
    
    
    @IBAction func close(sender: UIBarButtonItem) {
        dismissViewControllerAnimated(true, completion: nil)
    }

}


extension QRCodeViewController: AVCaptureMetadataOutputObjectsDelegate {

    
    // 建立通道
    func scan() {
        // 1.添加输入设备
        if !session.canAddInput(videoInput) {
            println("无法添加输入设备")
            return
        }
        session.addInput(videoInput)
        
        // 2.添加输出设备
        if !session.canAddOutput(dataoutput) {
            println("无法添加输出设备")
            return
        }
        session.addOutput(dataoutput)
        println("\(dataoutput.availableMetadataObjectTypes)")
        
        // 2.1 设置扫描数据类型(全部支持)
        dataoutput.metadataObjectTypes = dataoutput.availableMetadataObjectTypes
        
        // 2.2 设置输出代理
        dataoutput.setMetadataObjectsDelegate(self, queue: dispatch_get_main_queue())
        
        // 3.添加预览图层,最下边
        view.layer.insertSublayer(previewLayer, atIndex: 0)
        // 3.1添加扫描嘛的图层
        view.layer.insertSublayer(drawlayer, atIndex: 1)
        
        // 4.启动会话
        session.startRunning()
        
    }
    
    
    
    // MARK: - AVCaptureMetadataOutputObjectsDelegate代理,
    // 输出扫描到得数据
    func captureOutput(captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) {
        
        // 画图时清空图层
        clearDrawLayer()
        
        // 强制转换类型,用来获得corners属性,用来画图
        for dataObject in metadataObjects as! [AVMetadataMachineReadableCodeObject]{
            let obj = previewLayer.transformedMetadataObjectForMetadataObject(dataObject)
            drawCodeCorners(obj as! AVMetadataMachineReadableCodeObject)
            
            println("获取到得数据:\(obj)")
        }
        
    }

    
    // 绘制线
    private func createPath(points: NSArray)-> UIBezierPath {
        let path = UIBezierPath()
        var point = CGPoint()
        
        var index = 0
        // 起始点
        CGPointMakeWithDictionaryRepresentation(points[index++] as! CFDictionaryRef, &point)
        path.moveToPoint(point)
        
        // 遍历剩余的点
        while index < points.count {
            CGPointMakeWithDictionaryRepresentation(points[index++] as! CFDictionaryRef, &point)
            path.addLineToPoint(point)
        }
        
        // 关闭路径
        path.closePath()
        return path
    }
    
    
    // 绘制边线
    private func drawCodeCorners(codeObject: AVMetadataMachineReadableCodeObject) {
        // 判断数据,不然会崩溃
        if codeObject.corners.count == 0 {
            return
        }
        
        // 建立形状图层
        let shapelayer = CAShapeLayer()
        shapelayer.path = createPath(codeObject.corners).CGPath
        shapelayer.strokeColor = UIColor.greenColor().CGColor
        shapelayer.fillColor = UIColor.clearColor().CGColor
        shapelayer.lineWidth = 4
        
        
        // 添加形状图层
        drawlayer.addSublayer(shapelayer)
    }
    
    
    // 清空绘图图层
    private func clearDrawLayer() {
        // 判断sublayer是否为空,否则为空
        if drawlayer.sublayers != nil {
            for l in drawlayer.sublayers {
                l.removeFromSuperlayer()
            }
        }
    }

    
    
}
















